﻿using System;
using System.ServiceModel;

namespace CalculatorFour
{
    public class ClientProxy<TChannel> : IClientProxy<TChannel> where TChannel : ICommunicationObject
    {
        private readonly TChannel innerChannel;

        public ClientProxy(TChannel innerChannel)
        {
            this.innerChannel = innerChannel;
        }

        public TResult Execute<TResult>(Func<TChannel, TResult> operation)
        {
            TResult result = default(TResult);

            //Do not use the using statement when working with a WCF client: http://msdn.microsoft.com/en-us/library/aa355056.aspx)
            try
            {
                result = operation(innerChannel);
                innerChannel.Close();
            }
            catch (CommunicationException)
            {
                innerChannel.Abort();
            }
            catch (TimeoutException)
            {
                innerChannel.Abort();
            }
            catch (Exception)
            {
                innerChannel.Abort();
                throw;
            }

            return result;
        }
    }
}